home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / cut.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  4KB  |  194 lines

  1. /* cut - extract columns from a file or stdin.     Author: Michael J. Holme
  2.  *
  3.  *    Copyright 1989, Michael John Holme, All rights reserved.
  4.  *    This code may be freely distributed, provided that this notice
  5.  *    remains intact.
  6.  *
  7.  *    V1.1: 6th September 1989
  8.  *
  9.  *    Bugs, criticisms, etc,
  10.  *      c/o Mark Powell
  11.  *          JANET sq79@uk.ac.liv
  12.  *          ARPA  sq79%liv.ac.uk@nsfnet-relay.ac.uk
  13.  *          UUCP  ...!mcvax!ukc!liv.ac.uk!sq79
  14.  */
  15.  
  16. #include <sys/types.h>
  17. #include <ctype.h>
  18. #include <string.h>
  19. #include <errno.h>
  20. #include <stdio.h>
  21.  
  22. #define MAX_FIELD    80    /* Pointers to the beginning of each field
  23.              * are stored in columns[], if a line holds
  24.              * more than MAX_FIELD columns the array
  25.              * boundary is exceed. But unlikely at 80 */
  26. char *columns[MAX_FIELD];
  27.  
  28. #define MAX_ARGS    32    /* Maximum number of fields following -f or
  29.              * -c switches                    */
  30. int args[MAX_ARGS * 2];
  31. int num_args;
  32.  
  33. int mode;            /* 0 = dump stdin to stdout, 1=-f, 2=-c   */
  34. int flagi;            /* 1=-i, 0=no -i           */
  35. char delim = '\t';        /* default delimiting character      */
  36. FILE *fd;
  37. char *name;
  38. char line[BUFSIZ];
  39. extern int errno;
  40.  
  41. void cuterror(err)
  42. int err;
  43. {
  44.   static char *err_mes[] = {
  45.               "%s: syntax error\n",
  46.               "%s: position must be >0\n",
  47.               "%s: unknown option\n",
  48.               "%s: usage: cut [-f{args} [-i] [-d'x']]|[-c{args}] [filename [...]]\n",
  49.               "%s: line longer than BUFSIZ\n",
  50.               "%s: -d option not applicable\n",
  51.               "%s: -i option not applicable\n",
  52.          "%s: range must not decrease from left to right\n",
  53.               "%s: MAX_FIELD exceeded\n",
  54.               "%s: MAX_ARGS exceeded\n"
  55.   };
  56.   printf(err_mes[err - 1], name);
  57.   exit(err);
  58. }
  59.  
  60.  
  61. void get_args()
  62. {
  63.   int i = 0;
  64.   int arg_ptr = 0;
  65.   int flag;
  66.  
  67.   num_args = 0;
  68.   do {
  69.     if (num_args == MAX_ARGS) cuterror(10);
  70.     if (!isdigit(line[i]) && line[i] != '-') cuterror(1);
  71.  
  72.     args[arg_ptr] = 1;
  73.     args[arg_ptr + 1] = BUFSIZ;
  74.     flag = 1;
  75.  
  76.     while (line[i] != ',' && line[i] != 0) {
  77.         if (isdigit(line[i])) {
  78.             args[arg_ptr] = 0;
  79.             while (isdigit(line[i]))
  80.                 args[arg_ptr] = 10 * args[arg_ptr] + line[i++] - '0';
  81.             if (!args[arg_ptr]) cuterror(2);
  82.             arg_ptr++;
  83.         }
  84.         if (line[i] == '-') {
  85.             arg_ptr |= 1;
  86.             i++;
  87.             flag = 0;
  88.         }
  89.     }
  90.     if (flag && arg_ptr & 1) args[arg_ptr] = args[arg_ptr - 1];
  91.     if (args[num_args * 2] > args[num_args * 2 + 1]) cuterror(8);
  92.     num_args++;
  93.     arg_ptr = num_args * 2;
  94.   }
  95.   while (line[i++]);
  96. }
  97.  
  98.  
  99. void cut()
  100. {
  101.   int i, j, length, maxcol;
  102.  
  103.   while (fgets(line, BUFSIZ, fd)) {
  104.     length = strlen(line) - 1;
  105.     *(line + length) = 0;
  106.     switch (mode) {
  107.         case 0:    printf("%s", line);    break;
  108.         case 1:
  109.         maxcol = 0;
  110.         columns[maxcol++] = line;
  111.         for (i = 0; i < length; i++) {
  112.             if (*(line + i) == delim) {
  113.                 *(line + i) = 0;
  114.                 if (maxcol == MAX_FIELD) cuterror(9);
  115.                 columns[maxcol] = line + i + 1;
  116.                 while (*(line + i + 1) == delim && flagi) {
  117.                     columns[maxcol]++;
  118.                     i++;
  119.                 }
  120.                 maxcol++;
  121.             }
  122.         }
  123.         for (i = 0; i < num_args; i++) {
  124.             for (j = args[i * 2]; j <= args[i * 2 + 1]; j++)
  125.                 if (j <= maxcol) {
  126.                     printf("%s", columns[j - 1]);
  127.                     if (i != num_args - 1 || j != args[i * 2 + 1])
  128.                         putchar(delim);
  129.                 }
  130.         }
  131.         break;
  132.         case 2:
  133.         for (i = 0; i < num_args; i++) {
  134.             for (j = args[i * 2]; j <= (args[i * 2 + 1] > length ? length :
  135.                           args[i * 2 + 1]); j++)
  136.                 putchar(*(line + j - 1));
  137.         }
  138.     }
  139.     putchar('\n');
  140.   }
  141. }
  142.  
  143.  
  144. main(argc, argv)
  145. int argc;
  146. char *argv[];
  147. {
  148.   int flag;
  149.   int i = 1;
  150.  
  151.   name = argv[0];
  152.   if (argc == 1) cuterror(4);
  153.  
  154.   while (argv[i] != NULL && argv[i][0] == '-') {
  155.     switch (argv[i][1]) {
  156.         case 'd':
  157.         if (mode == 2) cuterror(6);
  158.         sprintf(line, "%.1s", &argv[i++][2]);
  159.         delim = line[0];
  160.         break;
  161.         case 'f':
  162.         sprintf(line, "%s", &argv[i++][2]);
  163.         mode = 1;
  164.         get_args();
  165.         break;
  166.         case 'c':
  167.         sprintf(line, "%s", &argv[i++][2]);
  168.         mode = 2;
  169.         get_args();
  170.         break;
  171.         case 'i':
  172.         if (mode == 2) cuterror(7);
  173.         flagi = 1;
  174.         i++;
  175.         break;
  176.         default:    cuterror(3);
  177.     }
  178.   }
  179.  
  180.   if (i < argc)
  181.     if ((fd = fopen(argv[i], "r")) == NULL) {
  182.         printf("%s: couldn't open %s\n", name, argv[i]);
  183.         exit(errno);
  184.     } else {
  185.         cut();
  186.         fclose(fd);
  187.     }
  188.   else {
  189.     fd = stdin;
  190.     cut();
  191.   }
  192.   exit(0);
  193. }
  194.